import datetime
import math
import os
import time

from flask import render_template, redirect, request, url_for, g, jsonify, abort, render_template_string
from sqlalchemy import func

from web.forms.user_forms import QuestionForm, AnswerForm
from web.models.boke_models import AnswerModel, QuestionModel, Category, Like, Credit, User, Collection
from application import db, app
from web.views.index import index_app
import uuid
from common.extend import check_favorite, up_and_down, oppose, support, cancle_support, cancel_oppose


# 拦截器
@index_app.before_request
def judge_user():
    lst = ['/public_article', '/detail_p', '/readall', '/public_answer', '/favorites', '/cancel_favorite',
           '/son_replay']
    if request.path in lst and not g.user:
        js_alert = "<script>alert('请先登录!');window.location.href='/';</script>"
        return render_template_string(js_alert)


@index_app.route('/')
def bbs():
    questions = QuestionModel.query.filter(QuestionModel.draft == 0, QuestionModel.check == 1,
                                           QuestionModel.hidden == 0).order_by(QuestionModel.create_time.desc()).all()[
                0:10]

    questions_num = QuestionModel.query.filter(QuestionModel.draft == 0, QuestionModel.check == 1,
                                               QuestionModel.hidden == 0).order_by(
        QuestionModel.create_time.desc()).count()

    total = math.ceil(questions_num / 10)

    # 点赞的文章
    like = Like.query.filter_by(user=g.user, type=1).all()
    like_lst = []
    for i in like:
        like_lst.append(i.article_id)

    # 点踩的文章
    dlike = Like.query.filter_by(user=g.user, type=2).all()
    dlike_lst = []
    for i in dlike:
        dlike_lst.append(i.article_id)
    return render_template('bbs.html', questions=questions, total=total, page=1, like_lst=like_lst, dlike_lst=dlike_lst)


# 页数
@index_app.route('/page/<int:page>')
def paginate(page):
    start = (page - 1) * 10
    questions = QuestionModel.query.filter(QuestionModel.draft == 0, QuestionModel.check == 1,
                                           QuestionModel.hidden == 0).order_by(QuestionModel.create_time.desc())
    articles = questions.all()[start:start + 10]
    questions_num = questions.count()

    total = math.ceil(questions_num / 10)

    # 点赞的文章
    like = Like.query.filter_by(user=g.user, type=1).all()
    like_lst = []
    for i in like:
        like_lst.append(i.article_id)

    # 点踩的文章
    dlike = Like.query.filter_by(user=g.user, type=2).all()
    dlike_lst = []
    for i in dlike:
        dlike_lst.append(i.article_id)
    return render_template('bbs.html', questions=articles, total=total, page=page, like_lst=like_lst,
                           dlike_lst=dlike_lst)


@index_app.route('/side')
def side():
    # 最新
    new_article = QuestionModel.query.filter(QuestionModel.draft == 0, QuestionModel.check == 1,
                                             QuestionModel.hidden == 0).order_by(
        QuestionModel.create_time.desc()).limit(7).all()

    new_list = []
    for i in new_article:
        dic = {'new_id': i.id, 'new_title': i.title[0:15] + '...', 'cover': i.cover,
               'times': i.update_time.strftime('%Y年%m月 %H:%M'), 'readcount': i.readcount}
        new_list.append(dic)

    # 最多
    most_article = QuestionModel.query.filter(QuestionModel.draft == 0, QuestionModel.check == 1,
                                              QuestionModel.hidden == 0).order_by(
        QuestionModel.readcount.desc()).limit(7).all()

    most_list = []
    for i in most_article:
        dic = {'new_id': i.id, 'new_title': i.title[0:15] + '...', 'cover': i.cover,
               'times': i.update_time.strftime('%Y年%m月 %H:%M'), 'readcount': i.readcount}
        most_list.append(dic)

    # 推荐
    rec_article = QuestionModel.query.filter(QuestionModel.draft == 0, QuestionModel.check == 1,
                                             QuestionModel.hidden == 0, QuestionModel.recomment == 1).order_by(
        func.random()).limit(7).all()

    rec_list = []

    for i in rec_article:
        dic = {'new_id': i.id, 'new_title': i.title[0:15] + '...', 'cover': i.cover,
               'times': i.update_time.strftime('%Y年%m月 %H:%M'), 'readcount': i.readcount}
        rec_list.append(dic)
    print(most_list)
    return jsonify([new_list, most_list, rec_list])


# 类型
@index_app.route('/category/<type>-<int:page>')
def classify(type, page):
    start = (page - 1) * 10
    questions = QuestionModel.query.join(Category).filter(QuestionModel.draft == 0, QuestionModel.check == 1,
                                                          QuestionModel.hidden == 0, Category.id == type).order_by(
        QuestionModel.create_time.desc())

    articles = questions.all()[start:start + 10]

    questions_num = questions.count()
    total = math.ceil(questions_num / 8)

    # 点赞的文章
    like = Like.query.filter_by(user=g.user, type=1).all()
    like_lst = []
    for i in like:
        like_lst.append(i.article_id)

    # 点踩的文章
    dlike = Like.query.filter_by(user=g.user, type=2).all()
    dlike_lst = []
    for i in dlike:
        dlike_lst.append(i.article_id)
    return render_template('category.html', questions=articles, total=total, page=page, type=type, like_lst=like_lst,
                           dlike_lst=dlike_lst)


# 搜索
@index_app.route('/search/<keyword>-<int:page>')
def search(keyword, page):
    if (len(keyword) > 10) or (keyword == '') or keyword == '%':
        abort(404)

    start = (page - 1) * 10
    questions = QuestionModel.query.filter(QuestionModel.draft == 0, QuestionModel.check == 1,
                                           QuestionModel.hidden == 0,
                                           QuestionModel.title.like('%' + keyword + '%')).order_by(
        QuestionModel.create_time.desc())
    articles = questions.all()[start:start + 10]
    questions_num = questions.count()
    total = math.ceil(questions_num / 10)

    # 点赞的文章
    like = Like.query.filter_by(user=g.user, type=1).all()
    like_lst = []
    for i in like:
        like_lst.append(i.article_id)

    # 点踩的文章
    dlike = Like.query.filter_by(user=g.user, type=2).all()
    dlike_lst = []
    for i in dlike:
        dlike_lst.append(i.article_id)
    return render_template('search.html', questions=articles, total=total, page=page,
                           keyword=keyword, like_lst=like_lst, dlike_lst=dlike_lst)


@index_app.route('/story')
def story():
    return render_template('worker.html')


@index_app.route("/public", methods=['GET', 'POST'])
def public_article():
    print('当前发布文章')
    global new_filename
    if request.method == 'GET':
        category = Category.query.all()
        return render_template("submit_article.html", category=category)
    else:
        new_filename = '默认.jpg'
        print(request.form)
        if not request.form.get('use_credit').isdigit():
            return jsonify({'credit': '应为数字！'})
        form = QuestionForm(request.form)
        print(form)
        if form.validate():
            f = request.files['files']
            # 保存文件资源
            try:
                if f:
                    filename = str(uuid.uuid4())
                    new_filename = filename + '.' + str(f.filename.split('.')[-1])
                    f.filename = new_filename

                    # 保存文件到指定文件夹
                    file_path = os.path.join(app.config['UPLOAD_FOLDER'], new_filename)
                    f.save(file_path)
            except Exception as e:
                print(e)

            title = request.form.get('title')
            content = request.form.get("content")
            detail = request.form.get("detail")
            credit = request.form.get("use_credit")
            category_id = request.form.get("category")
            hidden = request.form.get("hidden")

            question = QuestionModel(title=title, content=content, author_id=g.user.id,
                                     detail=detail, cover=new_filename, category_id=category_id, credit=credit,
                                     hidden=hidden, check=0)
            db.session.add(question)
            db.session.commit()
            # todo: 跳转到这篇问答的详情页
            return jsonify({'code': 200})
        else:
            return jsonify(form.errors)


# 详情页
@index_app.route("/detail/<int:id>")
def detail(id):
    global content, position, question, comment_list
    user_credit = False
    position = 0
    try:
        question = QuestionModel.query.filter_by(id=id).first()
        if question.author != g.user and g.user:
            question.readcount += 1
            db.session.add(question)
            db.session.commit()

        comment_list = []

        # 父评论 + 字评论
        father_comments = AnswerModel.query.filter_by(question_id=id, replyid=0).all()[0:5]
        for c in father_comments:
            lst = [c]
            son_comments = AnswerModel.query.filter_by(question_id=id, replyid=c.id).all()
            for s in son_comments:
                lst.append(s)
            comment_list.append(lst)

        if int(question.credit) != 0:
            content = str(question.content)[0:int(len(question.content) / 3)]
            position = content.rfind('</p>') + 4
            content = content[0:position]

            # 判断用户是否已经消耗过积分
            bool_usecredit = Credit.query.filter_by(author=g.user, target=id).first()
            if bool_usecredit:
                user_credit = False
                content = str(question.content)
            else:
                user_credit = True
        else:
            content = str(question.content)

    except Exception as e:
        print(e)
        abort(404)

    # 判断是否已经收藏
    if check_favorite(id):
        is_favorite = True
    else:
        is_favorite = False

    # 上一篇与下一篇
    dic = up_and_down(id)

    total = math.ceil(AnswerModel.query.filter_by(question_id=id, replyid=0).count() / 5)

    return render_template("detail.html", question=question, content=content,
                           user_credit=user_credit, position=position, is_favorite=is_favorite, dic=dic,
                           comment_list=comment_list, page=1, total=total)


# 审核
@index_app.route("/detail_p/<int:id>")
def detail_p(id):
    try:
        question = QuestionModel.query.filter_by(id=id).first()
    except Exception as e:
        print(e)
        abort(404)

    return render_template("detail_p.html", question=question)


# 积分阅读全部
@index_app.route('/readall', methods=['GET', 'POST'])
def readall():
    position = request.args.get('position')
    article_id = request.args.get('article_id')

    question = QuestionModel.query.filter_by(id=article_id).first()
    content = str(question.content)[int(position):]

    # 扣除相应的积分
    user = User.query.filter_by(id=g.user.id).first()
    if user.credit >= question.credit:
        # 添加积分明细
        credit = Credit(author_id=g.user.id, category='阅读文章', target=question.id, all_credit=question.credit)
        db.session.add(credit)
        db.session.commit()
        # 扣除相应积分
        user.credit -= question.credit
        db.session.add(user)
        db.session.commit()

        return content
    else:
        return jsonify({'code': 0})


# 评论
@index_app.route("/fa_comment", methods=["GET", 'POST'])
def public_answer():
    question_id = request.args.get('question_id')
    content = request.args.get('comment')
    if g.user == None:
        return jsonify({'code': 0})

    if len(content) >= 1 and len(content) <= 200:
        answer = AnswerModel(content=content, author_id=g.user.id, question_id=question_id)

        # 文章评论数加一
        question = QuestionModel.query.filter_by(id=question_id).first()
        question.replycount += 1

        db.session.add(answer)
        db.session.add(question)
        db.session.commit()
        return jsonify({'code': 1})
    else:
        return jsonify({'code': 2})


# 收藏文章
@index_app.route("/favorites", methods=["GET", 'POST'])
def favorites():
    id = request.args.get('id')
    if g.user:
        try:
            favorite = Collection.query.filter_by(author_id=g.user.id, question_id=id).first()
            if favorite is not None:
                favorite.canceled = 0
                db.session.commit()
            else:
                now = datetime.datetime.now()
                favorite = Collection(author_id=g.user.id, question_id=id, canceled=0, update_time=now)
                db.session.add(favorite)
                db.session.commit()
            return 'ok'
        except Exception as e:
            print(e)
            abort(404)
    else:
        return jsonify({'code': 0})


# 取消收藏
@index_app.route("/cancel_favorite", methods=["GET", 'POST'])
def cancel_favorite():
    id = request.args.get('id')
    if g.user:
        try:
            favorite = Collection.query.filter_by(author_id=g.user.id, question_id=id).first()
            favorite.canceled = 1
            db.session.commit()
            return 'ok'
        except:
            return 'no'
    else:
        return 'no'


# 回复评论
@index_app.route('son_replay', methods=['GET', 'POST'])
def son_replay():
    if g.user:
        article_id = request.args.get('article_id')
        comment_id = request.args.get('comment_id')
        comment_content = request.args.get('comment_content')
        comment = AnswerModel(content=comment_content, question_id=article_id, author_id=g.user.id,
                              replyid=comment_id)

        # 文章评论数加一
        question = QuestionModel.query.filter_by(id=article_id).first()
        question.replycount += 1

        db.session.add(comment)
        db.session.add(question)
        db.session.commit()
        return jsonify(1)
    else:
        return jsonify(0)


# 评论分页
@index_app.route('/comment_page/<int:question_id>-<int:page>', methods=['GET', 'POST'])
def comment_page(question_id, page):
    global content, position, question, comment_list
    user_credit = False
    position = 0
    try:
        question = QuestionModel.query.filter_by(id=question_id).first()
        question.readcount += 1
        db.session.add(question)
        db.session.commit()

        comment_list = []

        # 父评论 + 字评论
        start = (page - 1) * 5
        father_comments = AnswerModel.query.filter_by(question_id=question_id, replyid=0).all()[start:start + 5]
        for c in father_comments:
            lst = [c]
            son_comments = AnswerModel.query.filter_by(question_id=question_id, replyid=c.id).all()
            for s in son_comments:
                lst.append(s)
            comment_list.append(lst)

        if int(question.credit) != 0:
            content = str(question.content)[0:int(len(question.content) / 3)]
            position = content.rfind('</p>') + 4
            content = content[0:position]

            # 判断用户是否已经消耗过积分
            bool_usecredit = Credit.query.filter_by(author=g.user, target=question_id).first()
            if bool_usecredit:
                user_credit = False
                content = str(question.content)
            else:
                user_credit = True
        else:
            content = str(question.content)

    except Exception as e:
        print(e)
        abort(404)

    # 判断是否已经收藏
    if check_favorite(question_id):
        is_favorite = True
    else:
        is_favorite = False

    # 上一篇与下一篇
    dic = up_and_down(question_id)

    total = math.ceil(AnswerModel.query.filter_by(question_id=question_id, replyid=0).count() / 5)

    return render_template("detail.html", question=question, content=content,
                           user_credit=user_credit, position=position, is_favorite=is_favorite, dic=dic,
                           comment_list=comment_list, page=page, total=total)


# 点赞
@index_app.route("/like", methods=["POST"])
def like():
    article_id = request.args.get("article_id")
    if Like.query.filter_by(user=g.user, article_id=article_id, type=2).first():
        return jsonify({'code': 'no'})

    like = Like.query.filter_by(user=g.user, article_id=article_id).first()

    if g.user:
        if not like or like.type == 0:
            print('点赞成功')
            support(article_id)
            like_num = QuestionModel.query.filter_by(id=article_id).first().up
            return jsonify({'code': 1, 'num': like_num})
        else:
            print('点赞失败')
            # 取消点赞
            cancle_support(article_id)
            like_num = QuestionModel.query.filter_by(id=article_id).first().up
            return jsonify({'code': 2, 'num': like_num})

    else:
        return jsonify({'code': 0})


# 点踩
@index_app.route("/dlike", methods=["POST"])
def dlike():
    article_id = request.args.get("article_id")

    if Like.query.filter_by(user=g.user, article_id=article_id, type=1).first():
        return jsonify({'code': 'no'})

    like = Like.query.filter_by(user=g.user, article_id=article_id).first()
    if g.user:
        if not like or like.type == 0:
            print('成功点踩')
            oppose(article_id)
            dlike_num = QuestionModel.query.filter_by(id=article_id).first().down
            return jsonify({'code': 1, 'num': dlike_num})
        else:
            print('失败点踩')
            # 取消点踩
            cancel_oppose(article_id)
            dlike_num = QuestionModel.query.filter_by(id=article_id).first().down
            return jsonify({'code': 2, 'num': dlike_num})
    else:
        return jsonify({'code': 0})


# 保存文章图片
@index_app.route('/test', methods=['GET', 'POST'])
def text():
    try:
        f = request.files['article-img']

        filename = str(uuid.uuid4())
        new_filename = filename + str(time.time()) + '.' + str(f.filename.split('.')[-1])
        print(new_filename)
        f.filename = new_filename

        # 保存文件到指定文件夹
        file_path = os.path.join(app.config['UPLOAD_ARTICLE'], new_filename)
        f.save(file_path)

        error = {
            "errno": 0,
            "data": {
                "url": f"../../static/article_img/{new_filename}",
                "alt": "yyy",
                "href": ""
            }
        }
        print(error)
        return jsonify(error)
    except:
        error = {
            "errno": 1,
            "message": '0'
        }
        return jsonify(error)
